using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Drawing;

namespace DotNetSide.SqlScriptGenerator
{
    class SqlSyntaxHighlightRichTextBox : RichTextBox
    {
        private String[] keywords1 = { "insert", "into", "values", "begin", 
            "transaction", "use", "alter", "table", "nocheck", "constraint", 
            "delete", "from", "commit", "check", "IF", "EXISTS", "SELECT", 
            "WHERE", "BEGIN", "UPDATE", "SET", "END", "ELSE"};
        private String[] keywords2 = { "all", "null" };

        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                this.HighlightText(value);
            }
        }

        private void HighlightText(string text)
        {
            Regex r = new Regex("\\n");
            String[] lines = r.Split(text);
            foreach (string l in lines)
            {
                ParseLine(l);
            }
        }

        private void ParseLine(string line)
        {
            Color defaultColor = Color.Black;
            Regex r = new Regex("([ \\t{}():;])|('[^']*')|('[^\r]*)(\r\n)?|(\\[[^\\[]*\\])");
            String[] tokens = r.Split(line);
            foreach (string token in tokens)
            {
                // single line comment
                if (token.Contains("--"))
                {
                    defaultColor = Color.Green;
                }

                this.SelectionColor = defaultColor;
                this.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);

                if (defaultColor != Color.Green)
                {
                    this.EvaluateToken(token, keywords1, Color.Blue);
                    this.EvaluateToken(token, keywords2, Color.Gray);

                    if (token.StartsWith("'") & token.EndsWith("'"))
                    {
                        this.SelectionColor = Color.Red;
                    }

                    if (token.StartsWith("[") & token.EndsWith("]"))
                    {
                        this.SelectionFont = new Font("Courier New", 10, FontStyle.Italic);
                    }
                }

                this.SelectedText = token;
            }
        }

        private void EvaluateToken(string token, string[] keywords, Color color)
        {
            for (int i = 0; i < keywords.Length; i++)
            {
                if (keywords[i].ToLower() == token.ToLower())
                {
                    this.SelectionColor = color;
                    this.SelectionFont = new Font("Courier New", 10, FontStyle.Bold);
                    break;
                }
            }
        }

        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);
        }
    }
}
